package com.norns.torque

import android.content.ContentValues
import android.net.Uri
import android.os.Environment
import android.os.Environment.DIRECTORY_DOCUMENTS
import android.os.Environment.getExternalStoragePublicDirectory
import android.provider.MediaStore
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.norns.torque.entrty.AppDatabase
import com.norns.torque.entrty.ScaleBean
import com.norns.torque.entrty.ScaleDao
import com.norns.torque.utils.AppContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.apache.poi.hssf.usermodel.HSSFCellStyle
import org.apache.poi.ss.usermodel.CellStyle
import org.apache.poi.ss.usermodel.Font
import org.apache.poi.ss.usermodel.IndexedColors
import org.apache.poi.ss.usermodel.Workbook
import org.apache.poi.ss.util.WorkbookUtil
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import timber.log.Timber
import java.io.IOException
import java.io.OutputStream
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter


class ExcelViewModel : ViewModel() {
    private var scaleDao: ScaleDao? = null
    private val _viewState = MutableLiveData<String>()
    val viewState = _viewState as LiveData<String>

    private val _listScaleLiveData = MutableLiveData<List<ScaleBean>>()
    val listScale = _listScaleLiveData as LiveData<List<ScaleBean>>

    fun initDataBase() {
        if (null == scaleDao) {
            viewModelScope.launch {
                withContext(Dispatchers.IO) {
                    val db = AppDatabase.getInstance(AppContext.context)
                    scaleDao = db.scaleDao()
                    if (null == scaleDao) {
                        scaleDao = db.scaleDao()
                    }
                    getAllScale()
                    Timber.d("init scaleDao==null:${scaleDao == null}")
                }
            }
        }
    }

    fun deleteScale(scaleBean: ScaleBean) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                scaleDao?.let { dao ->
                    dao.delete(scaleBean)
                    getAllScale()
                }
            }
        }
    }
    fun deleteAllScale(){
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                scaleDao?.let { dao ->
                    dao.deleteAll()
                    getAllScale()
                }
            }
        }
    }

    private fun getAllScale() {
        scaleDao?.let { dao ->
            val list = dao.all
            list.forEachIndexed { index, scaleBean ->
                scaleBean.count = "${index + 1}"
            }
            list.reverse()
            _listScaleLiveData.postValue(list)
        }
    }

    fun insertScale(scaleBean: ScaleBean) {
        scaleDao?.let { dao ->
            dao.insert(scaleBean)
        }
    }

    fun createExcelFile() {
        viewModelScope.launch(Dispatchers.IO) {
            val workbook: Workbook = XSSFWorkbook()
            val sheet = workbook.createSheet(WorkbookUtil.createSafeSheetName("Sheet1"))
            val cellStyle: CellStyle = workbook.createCellStyle()
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER)

            val headerRow = sheet.createRow(0) //第一行

            val cell01 = headerRow.createCell(0)
            cell01.cellStyle = cellStyle
            cell01.setCellValue("序号")

            val cell02 = headerRow.createCell(1)
            cell02.cellStyle = cellStyle
            cell02.setCellValue("设备")

            val cell03 = headerRow.createCell(2)
            cell03.cellStyle = cellStyle
            cell03.setCellValue("日期")

            val cell04 = headerRow.createCell(3)
            cell04.cellStyle = cellStyle
            cell04.setCellValue("时间")

            val cell05 = headerRow.createCell(4)
            cell05.cellStyle = cellStyle
            cell05.setCellValue("精度")

            val cell06 = headerRow.createCell(5)
            cell06.cellStyle = cellStyle
            cell06.setCellValue("目标值")

            val cell07 = headerRow.createCell(6)
            cell07.cellStyle = cellStyle
            cell07.setCellValue("实际值")

            val cell08 = headerRow.createCell(7)
            cell08.cellStyle = cellStyle
            cell08.setCellValue("单位")

            val cell09 = headerRow.createCell(8)
            cell09.cellStyle = cellStyle
            cell09.setCellValue("合格")

            sheet.setColumnWidth(1, 3500)
            scaleDao?.let { dao ->
                val list = dao.getAll()
                for ((index, scaleBean) in list.withIndex()) {
                    val position = index + 1
                    val dataRow = sheet.createRow(position)

                    val cell0 = dataRow.createCell(0)
                    cell0.cellStyle = cellStyle
                    cell0.setCellValue("${position}")

                    val cell1 = dataRow.createCell(1)
                    cell1.cellStyle = cellStyle
                    cell1.setCellValue(scaleBean.deviceName)

                    val f1: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy.MM.dd")
                    val dataString = scaleBean.date.format(f1)
                    dataRow.createCell(2).setCellValue(dataString)

                    val f2: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss")
                    val timeString = scaleBean.date.format(f2)
                    dataRow.createCell(3).setCellValue(timeString)

                    dataRow.createCell(4).setCellValue(scaleBean.precisionDegree.toString())
                    dataRow.createCell(5).setCellValue(scaleBean.targetValue.toString())
                    dataRow.createCell(6).setCellValue(scaleBean.value.toString())
                    dataRow.createCell(7).setCellValue(scaleBean.unit.toString())
                    val offset = scaleBean.targetValue * (scaleBean.precisionDegree / 100f)
                    val upValue = scaleBean.targetValue + offset
                    val dowValue = scaleBean.targetValue - offset
                    val style = workbook.createCellStyle()
                    // 创建字体样式
                    val font: Font = workbook.createFont()
                    // true为加粗，默认为不加粗
                    font.setBold(true)
                    // 设置字体颜色，颜色和上述的颜色对照表是一样的
                    font.setColor(IndexedColors.WHITE.getIndex())
                    // 将字体样式设置到单元格样式中
                    style.setFont(font)
                    val cell7 = dataRow.createCell(8)
                    if (scaleBean.value < dowValue) {
                        font.setColor(IndexedColors.BLACK.getIndex())
                        cell7.setCellValue("Low")
                        cell7.cellStyle = style
                    } else if (scaleBean.value > upValue) {
                        font.setColor(IndexedColors.RED.getIndex())
                        cell7.setCellValue("High")
                        cell7.cellStyle = style
                    } else {
                        font.setColor(IndexedColors.GREEN.getIndex())
                        cell7.setCellValue("Ok")
                        cell7.cellStyle = style
                    }
                }
                val localDateTime = LocalDateTime.now()
                val f2: DateTimeFormatter = DateTimeFormatter.ofPattern("MM-dd-HH-mm")
                val dataString = localDateTime.format(f2)
                writeTxtToFile(workbook, "${dataString}")
            }
        }
    }

    // 将字符串写入到文本文件
    private fun writeTxtToFile(workbook: Workbook, fileName: String) {
        //获取外部存储器的状态
        val state = Environment.getExternalStorageState()
        //主要有两种状态
        //外部状态可用
        if (Environment.MEDIA_MOUNTED == state) {
            // 获取下载目录
            val downloadsDir = getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS)
            try {
                val documentFile = DocumentFile.fromFile(downloadsDir)
                val subDocumentFile = documentFile.createFile("application/vnd.ms-excel", fileName)
                val uri = subDocumentFile?.uri
                if (uri==null){
                    _viewState.postValue("下载失败")
                    return
                }
                val outputStream: OutputStream? = AppContext.context.getContentResolver().openOutputStream(uri)
                workbook.write(outputStream)
                // 4. 刷新存储访问权限（MediaStore API需要）
                if (documentFile.exists()) {
                    val values = ContentValues()
                    values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
                    values.put(MediaStore.MediaColumns.MIME_TYPE, "application/vnd.ms-excel")
                    values.put(MediaStore.MediaColumns.RELATIVE_PATH, DIRECTORY_DOCUMENTS)
                    val uri: Uri? = AppContext.context.getContentResolver().insert(MediaStore.Files.getContentUri("external"), values)
                    uri?.let {
                        // 通知系统文件已经更改
                        AppContext.context.getContentResolver().notifyChange(uri, null)
                    }
                }
                Timber.d("${uri.path}")
                _viewState.postValue("已保存到${uri.path}")
            } catch (e: IOException) {
                e.printStackTrace()
                // 处理异常情况
                _viewState.postValue("下载失败")
            }
        }
    }
}